package cn.harry.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @author harry
 * @公众号 Harry技术
 * Spring Boot 3 集成 Spring Security（2） 授权: https://mp.weixin.qq.com/s/HzzcYIQLnch_7r7wdUarew
 */
@Configuration
@EnableWebSecurity()
@EnableMethodSecurity(securedEnabled = true) // 开启方法级别的权限控制
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        // 公开访问
                        .requestMatchers("/").permitAll()
                        // 只有 ROOT 角色可以访问 /admin 目录下的资源
                        .requestMatchers("/admin/**").hasRole("ROOT")
                        // USER 和 ROOT 角色都可以访问 /user 目录下的资源
                        .requestMatchers("/user/**").hasAnyRole("ROOT", "USER")
                        // 其他接口需认证
                        .anyRequest().authenticated()
                )

                // 开启基于表单的登录
                .formLogin(Customizer.withDefaults())
//                // 开启注销功能
//                .logout(Customizer.withDefaults())
//                // 开启 HTTP Basic 认证
//                .httpBasic(Customizer.withDefaults())
//                // 开启 CSRF 防护
//                .csrf(Customizer.withDefaults())
//                // 开启跨域资源共享
//                .cors(Customizer.withDefaults())
        ;

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        // 创建用户
        UserDetails admin = User.builder()
                .username("admin")
                .password(passwordEncoder.encode("123456"))
                // 设置用户角色为ROOT
                .roles("ROOT")
                .build();

        UserDetails user = User.builder()
                .username("user")
                .password(passwordEncoder.encode("123456"))
                // 设置用户角色为USER
                .roles("USER")
                .build();

        // 将用户添加到内存中
        manager.createUser(admin);
        manager.createUser(user);
        return manager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 使用 BCrypt 进行密码加密
        return new BCryptPasswordEncoder();
    }
}
